package org.third.security.classloader;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import sun.security.pkcs.PKCS7;
import sun.security.pkcs.SignerInfo;

public class ClassLoaderHello {
    static final char[] hexc = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    static String toHex(byte[] arg) {
        StringBuffer arg0 = new StringBuffer(arg.length * 2);

        for (int arg1 = 0; arg1 < arg.length; ++arg1) {
            arg0.append(hexc[arg[arg1] >> 4 & 15]);
            arg0.append(hexc[arg[arg1] & 15]);
        }
        return arg0.toString();
    }

    public static boolean isBlockOrSF(String arg) {
        return arg.endsWith(".SF") || arg.endsWith(".DSA") || arg.endsWith(".RSA") || arg.endsWith(".EC");
    }

    @SuppressWarnings({ "resource", "unused" })
    public static void main(String[] args) {

        System.setProperty("sun.misc.URLClassPath.debug", "true");
        URL[] urls = new URL[] {};
        MyClassLoader classLoader = new MyClassLoader(urls, null);
        String path = "C:/IDM/help/server/resources/security/idm-jaas1-signed.jar";
        path = "C:/IDM/help/server/resources/security/idm-jaas1-signed-error.jar";
        try {
            JarFile jar = new JarFile(path);
            for (java.util.Enumeration<JarEntry> entryEnum = jar.entries(); entryEnum.hasMoreElements();) {
                // META-INF/
                // META-INF/MANIFEST.MF
                // META-INF/TOMCAT1.RSA
                // META-INF/TOMCAT1.SF
                // org/
                // org/third/
                // org/third/security/
                // org/third/security/jaas/
                // org/third/security/jaas/EmailPrincipal.class
                // org/third/security/jaas/HelloLoginModule1.class
                // org/third/security/jaas/UniqueNamePrincipal.class

                JarEntry jarEntry = entryEnum.nextElement();
                String entryName = jarEntry.getName();
                System.out.println(entryName);
                if (entryName.startsWith("META-INF/")) {
                    if (!jarEntry.isDirectory()) {
                        if (entryName.equals("META-INF/MANIFEST.MF")) {
                            System.out.println(new String(fileToByte(jar.getInputStream(jarEntry))));
                        } else if (entryName.endsWith(".RSA") || entryName.endsWith(".DSA") || entryName.endsWith(".EC")) {
                            InputStream ins = jar.getInputStream(jarEntry);
                            byte[] encodedKey = fileToByte(ins);
                            PKCS7 pkcs7 = new PKCS7(encodedKey);
                            sun.security.pkcs.SignerInfo[] signerInfos = pkcs7.getSignerInfos();
                            for (SignerInfo info : signerInfos) {
                                ArrayList<X509Certificate> certficateChains = info.getCertificateChain(pkcs7);
                                System.out.println(certficateChains);
                            }
                            encodedKey = Base64.getMimeDecoder().decode(encodedKey);
                            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
                        } else {

                        }

                    } else {

                    }
                }
            }
//            Manifest maf = jar.getManifest();
//            ZipEntry entry1 = jar.getEntry("/META-INF/MANIFEST.MF");
//            JarEntry entry2 = jar.getJarEntry("/META-INF/MANIFEST.MF");
//            
//            Manifest mf1 = new Manifest(new ByteArrayInputStream(new byte[] {}));
//
////             jar.getInputStream(ze)
//
//            classLoader.addJar(new File(path).toURI().toURL());
//            Class<?> clazz = classLoader.loadClass("org.third.security.jaas.EmailPrincipal");
//            Method md5Method = clazz.getDeclaredMethod("getName");
//
//            Object returnValue = md5Method.invoke(clazz.getConstructor(String.class).newInstance("test1"), new Object[] {});
//
//            System.out.println("result=" + returnValue.toString());
//            classLoader.close();

            /**
             * ClassLoader cl = new URLClassLoader(new URL[]{new File(path).toURI().toURL()}); Class<?> clazz2 =
             * classLoader.loadClass("org.apache.commons.codec.digest.DigestUtils"); Method md5Method2 =
             * clazz.getDeclaredMethod("md5Hex",byte[].class); Object returnValue2 =
             * md5Method.invoke(clazz2.newInstance(), "hello world".getBytes("utf-8"));
             * System.out.println("length="+returnValue2.toString().length()+",result="+returnValue2.toString());
             **/
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static byte[] fileToByte(InputStream fis) throws IOException {
        byte[] content = new byte[fis.available()];
        fis.read(content);
        fis.close();
        return content;
    }

    static class MyClassLoader extends URLClassLoader {

        public MyClassLoader(URL[] urls) {
            super(urls);
        }

        public MyClassLoader(URL[] urls, ClassLoader parent) {
            super(urls, parent);
        }

        public void addJar(URL url) {
            this.addURL(url);
        }

        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            // TODO Auto-generated method stub
            return super.loadClass(name);
        }

        @Override
        protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            // TODO Auto-generated method stub
            return super.loadClass(name, resolve);
        }

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            // TODO Auto-generated method stub
            return super.findClass(name);
        }

    }
}
